package com.example.covid19.controller;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.covid19.common.Dto.Editdto;
import com.example.covid19.common.Dto.Stuall;
import com.example.covid19.common.lang.Result;
import com.example.covid19.entity.Room;
import com.example.covid19.entity.Student;
import com.example.covid19.entity.Studentinfo;
import com.example.covid19.mapper.StudentMapper;
import com.example.covid19.mapper.StudentinfoMapper;
import com.example.covid19.service.RoomService;
import com.example.covid19.service.StudentService;
import com.example.covid19.service.StudentinfoService;
import com.example.covid19.service.impl.StudentinfoServiceImpl;
import com.example.covid19.util.ExcelReader;
import com.example.covid19.util.SecretUtil;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import com.example.covid19.common.Dto.RegisterDto;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.example.covid19.util.SecretUtil.secret;
import static org.apache.commons.lang.StringUtils.isNotBlank;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author BaiZhengChun
 * @since 2023-03-07
 */
@RestController
@Slf4j
@RequestMapping("/student")
public class StudentController {
    private final StudentMapper studentMapper;
    private final StudentinfoMapper studentinfoMapper;
    private final StudentinfoService studentinfoService;
    private final StudentService studentService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    RoomService roomService;

    public StudentController(StudentMapper studentMapper, StudentinfoMapper studentinfoMapper, StudentinfoService studentinfoService, StudentService studentService) {
        this.studentMapper = studentMapper;
        this.studentinfoMapper = studentinfoMapper;
        this.studentinfoService = studentinfoService;
        this.studentService = studentService;
    }
    @RequestMapping("/login")
    public Result login(@RequestBody Student student2) {
        Student student = studentService.getOne(new QueryWrapper<Student>().eq(
                "studentid", Integer.valueOf(student2.getStudentid())
        ));
        if (student == null) {
            return Result.fail(401, "用户不存在", null);
        }

        boolean flag = student.getPassword().equals(
                SecureUtil.hmacSha1(secret)
                        .digestHex(student2.getPassword())
        );
        Studentinfo studentinfo = studentinfoService.getOne(new QueryWrapper<Studentinfo>().eq(
                "studentid", Integer.valueOf(student2.getStudentid())
        ));
        if (flag) {
            StpUtil.login(student.getStudentid());
//            System.out.println(StpUtil.getTokenValue());
            Map<String, Object> objectMap = new HashMap<>(2);
            objectMap.put("token", StpUtil.getTokenInfo());
            student.setPassword(null);
            objectMap.put("student", studentinfo);
            return Result.success(200, "登陆成功", objectMap);
        } else {
            return Result.fail(400, "密码错误", null);
        }
    }

    /**
     *
     * @param multipartFile
     * @return使用excel导入学生信息，这里返回给前端进行确认
     */
    @RequestMapping("/upload")
    public Result upLoad(@RequestParam("file") MultipartFile multipartFile) {
        log.info("文件上传开始");
        log.info("文件{}", multipartFile.getOriginalFilename());
        JSONArray jsonArray = JSONUtil.parseObj(ExcelReader.upload(multipartFile, Student.class).getData()).getJSONArray("success");
        List<Student> studentList = jsonArray.toList(Student.class)
                .stream()
                .peek(v -> v.setPassword(SecureUtil.hmacSha1(secret).digestHex(v.getPassword())))
                .collect(Collectors.toList());
//        System.out.println(studentList);
        return Result.success(200,"ok",studentList);
    }

    /**
     *
     * @param studentList
     * @return 这个是上传学生
     */
    @RequestMapping("stuimper")
    public Result stuimper(@RequestBody List<Student> studentList){
        System.out.println(studentList);
        boolean flag = studentService.saveBatch(studentList);
        if (flag){
            return Result.success(200,"成功",null);
        }else {
            return Result.fail(401,"保存失败",null);
        }
    }

    /**
     *
     * @param student
     * @return 单个添加学生
     */
    @RequestMapping("add")
    public Result add(@RequestBody Stuall student){
        Student student1 = new Student();
        student1.setName(student.getName());
        student1.setPassword(SecureUtil.hmacSha1(secret).digestHex(student.getPassword()));
        student1.setStudentid(123);
        student1.setPhone(student.getPhone());
        student1.setSex(String.valueOf(student.getSex()));
        student1.setStudentid(Integer.valueOf(student.getStudentid()));
        student1.setCcid(Integer.valueOf(student.getArea()[3]));
        student1.setRid(roomService.getOne(new QueryWrapper<Room>().
                eq("lid",student.getBuilder()[0]).
                eq("rid",student.getBuilder()[1])).getId());
        boolean flag = studentService.save(student1);
        if (flag){
            return Result.success(200,"成功",null);
        }else {
            return Result.fail(401,"保存失败",null);
        }
    }

    /**
     *
     * @param student
     * @return 修改学生
     */
    @RequestMapping("edit")
    public Result edit(@RequestBody Stuall student){
        Student student1 = new Student();
        student1.setName(student.getName());
        student1.setPassword(SecureUtil.hmacSha1(secret).digestHex(student.getPassword()));
        student1.setStudentid(123);
        student1.setPhone(student.getPhone());
        student1.setSex(String.valueOf(student.getSex()));
        student1.setStudentid(Integer.valueOf(student.getStudentid()));
        student1.setCcid(Integer.valueOf(student.getArea()[3]));
        boolean flag = studentService.updateById(student1);
        if (flag){
            return Result.success(200,"成功",null);
        }else {
            return Result.fail(401,"保存失败",null);
        }
    }
    @RequestMapping("getinfo")
    public Result getinfo(HttpServletRequest httpServletRequest){
        String satoken = httpServletRequest.getHeader("satoken");
//        System.out.println("satoken="+satoken);
        Studentinfo studentinfo = studentinfoService.getOne(new QueryWrapper<Studentinfo>().eq(
                "studentid",StpUtil.getLoginIdByToken(satoken)
        ));

        if (studentinfo!=null){
            return Result.success(200,"成功",studentinfo);
        }else {
            return Result.fail(400,"失败",null);
        }
    }
    @RequestMapping("/test2")
    public Result tes2t(){
        String s = "123456";
        Student student = new Student();
        student.setName("test");
        student.setStudentid(001);
        student.setPassword(SecureUtil.hmacSha1(secret).digestHex(s));
        student.setPhone("123456789");
        student.setFacetoken("fgwregrwefrwefgr");
        student.setCcid(6);
        studentService.save(student);
        return Result.success(200,"成功",null);
    }
    private String getFieldValue(Studentinfo student, String fieldName) {
        try {
            Field field = student.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            return (String) field.get(student);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     *
     * @param student
     * @return后台界面查询 条件为空则不查
     */
    @RequestMapping("filtestudent")
    public Result filtestudent(@RequestBody Studentinfo student){
            QueryWrapper<Studentinfo> queryWrapper = new QueryWrapper<>();
            Stream.of("name", "phone", "studentid","majeurname","rname","cname")
                    .filter(fieldName -> isNotBlank(getFieldValue(student, fieldName)))
                    .forEach(fieldName -> queryWrapper.eq(fieldName, getFieldValue(student, fieldName)));
            List<Studentinfo> studentList = studentinfoService.list(queryWrapper);
            return Result.success(studentList);
    }
    @RequestMapping("/register")
    public Result register(RegisterDto registerDto){
        String code = registerDto.getCode();
        String c = stringRedisTemplate.opsForValue().get(registerDto.getPhone());
        System.out.println(stringRedisTemplate.opsForValue().get(registerDto.getPhone()));
        System.out.println(code);
        boolean codeFlag = code.equals(c);
        if (!codeFlag) {
            return Result.fail(406, "验证码不正确", null);
        }
        String secret = SecretUtil.secret;
        Student student = new Student();
        student.setStudentid(registerDto.getStudentid());
        student.setName(registerDto.getUsername());
        student.setFacetoken(registerDto.getFacetoken());
        student.setPassword(SecureUtil.hmacSha1(secret).digestHex(registerDto.getPassword()));
        student.setPhone(registerDto.getPhone());
        Student student2 = studentService.getOne(new QueryWrapper<Student>().eq("studentid",registerDto.getStudentid()));
        if (student2 != null) {
            return Result.fail(406, "用户已经存在", null);
        }
        boolean flag = studentService.save(student);
        if (!flag) {
            return Result.fail(406, "用户创建失败", null);
        }
        else {
            return Result.success(200,"用户创建成功",null);
        }
    }
    @RequestMapping("/sendMessage")
    public void sendMessage(RegisterDto registerDto) {
        try {
            System.out.println(registerDto.getPhone());
            // 实例化一个认证对象，入参需要传入腾讯云账户secretId，secretKey,此处还需注意密钥对的保密
            // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
            Credential cred = new Credential("AKID73mGVVFk00kFVVFl24qMcdOt9AvQggRw", "HJ5buxlJbdV8WeW9WdU6SYOzKQHvLVv6");
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("sms.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            SmsClient client = new SmsClient(cred, "ap-guangzhou", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            SendSmsRequest req = new SendSmsRequest();
            String[] phoneNumberSet1 = {String.valueOf(registerDto.getPhone())};
            req.setPhoneNumberSet(phoneNumberSet1);
            req.setSmsSdkAppId("1400527069");
            req.setSignName("辽东学院");
            req.setTemplateId("972395");
            String code = RandomStringUtils.randomNumeric(6);
            System.out.println(code);
            // 验证码，附加文字，但是不能超过12个字符
            String[] templateParamSet1 = {code};
            req.setTemplateParamSet(templateParamSet1);
            // 返回的resp是一个SendSmsResponse的实例，与请求对象对应
            SendSmsResponse resp = client.SendSms(req);
            // 输出json格式的字符串回包
            System.out.println(SendSmsResponse.toJsonString(resp));
            long codeTimeout = 300;
//            redisUtils.setValue(phone, code, codeTimeout);
            stringRedisTemplate.opsForValue().set(String.valueOf(registerDto.getPhone()), code);
        } catch (TencentCloudSDKException e) {
            e.printStackTrace();
        }
    }

}
